# encoding:utf-8
import json

from redis import Redis
import time

conn = Redis(host="192.168.35.211", port=6379, db=0)


# Press Shift+F10 to execute it or replace it with your code.
# Press Double Shift to search everywhere for classes, files, tool windows, actions, and settings.


def print_hi(name):
    # Use a breakpoint in the code line below to debug your script.
    print(f'Hi, {name}')  # Press Ctrl+F8 to toggle the breakpoint.


def check_token(conn, token):
    return conn.hget('login:', token)


def update_token(conn, token, user, item=None):
    timestamp = time.time()
    conn.hset('login:', token, user)
    conn.zadd('recent:', {token: timestamp})
    if item:
        conn.zadd('viewed:' + token, {item: timestamp})
        conn.zremrangebyrank('viewed:' + token, 0, -26)
        conn.zincrby('viewed:', -1, item)


QUIT = False
LIMIT = 1000000


def clean_sessions(conn):
    while not QUIT:
        size = conn.zcard('recent:')
        if size < LIMIT:
            time.sleep(1)
            continue
        end_index = min(size - LIMIT, 100)
        tokens = conn.zrange('recent:', 0, end_index - 1)
        sessions_keys = []
        for token in tokens:
            sessions_keys.append('viewd:' + token)
        # 通过*这种语法可以批量删除key
        conn.delete(*sessions_keys)
        # 批量删除散列里面的key
        conn.hdel('login:', *tokens)
        # 批量删除有序集合里面的key
        conn.zrem('recent:', *tokens)


def add_to_cart(conn, session, item, count):
    if count <= 0:
        conn.hdel('cart:' + session, item)
    else:
        conn.hset('cart:' + session, item, count)


def cache_request(conn, request, callback):
    if not_can_cache(conn, request):
        return callback(request)
    page_key = 'cache:' + hash_request(request)
    content = conn.get(page_key)
    if not content:
        content = callback(request)
        conn.setex(page_key, 300, content)
    return content


def not_can_cache(conn, request):
    return False


def can_cache(conn, request):
    item_id = extract_item_id(request)
    if not item_id:
        return False
    rank = conn.zrank('viewed:', item_id)
    return rank is not None and rank < 10000


def extract_item_id(request):
    return "item:123"


def callback(request):
    print_hi('PyCharm')
    return 21212


def hash_request(request):
    return "9527"


def schedule_row_cache(conn, row_id, delay):
    conn.zadd('delay:', {row_id: delay})
    conn.zadd('schedule:', {row_id: time.time()})


def cache_rows(conn):
    while not QUIT:
        next = conn.zrange('schedule:', 0, 0, withscores=True)
        now = time.time()
        if not next or next[0][1] > now:
            time.sleep(.05)
            continue
        row_id = next[0][0]

        delay = conn.zscore('delay:', row_id)
        if delay < 0:
            conn.zrem('delay:', row_id)
            conn.zrem('schedule:', row_id)
            conn.delete('inv:' + row_id)
            continue
        row = {'name': 'hyman', 'age': 12}
        conn.zadd('schedule:', {12: now + delay})
        conn.set('inv:' + str(row_id), json.dumps(row))


def recale_view(conn):
    while not QUIT:
        # 删除20000名之后的商品
        conn.zremrangebyrank('viewed:', 0, -20001)
        # 将原来的分值乘以0.5
        conn.zinterstore('viewed:', {'viewed:': 0.5})
        time.sleep(300)


# Press the green button in the gutter to run the script.
if __name__ == '__main__':
    can_cache(conn,None)
    recale_view(conn)
    update_token(conn, "1234567890", "hyman:9627", 'item:123')
    recale_view(conn)
    obj = check_token(conn, "1234567890")
    add_to_cart(conn, "1234567890", "item:123", 2)
    add_to_cart(conn, "1234567890", "item:123", 0)
    cache_request(conn, "request", callback)
    schedule_row_cache(conn, row_id=12, delay=60)
    cache_rows(conn)
    recale_view(conn)

# See PyCharm help at https://www.jetbrains.com/help/pycharm/
